import type { Ref } from "vue";
import { toValue } from "vue";
import { validateFormLogic } from "@/views/formgen/utils/expression";
import { BasicComponent, FieldVisibilityState } from "../types/form";
import { getCheckedLabel, isLabelTag } from "@/views/formgen/components/GenerateForm/FormItemLabel";
import { useUserFormInject } from "@/views/formgen/components/GenerateForm/hooks/useUserFormInject";
import { LogicLevel, LogicOperation } from "../../BizProjectForm/FormLogic";

interface FieldVisibilityChange {
  fieldId: string;
  isVisible: boolean;
  previousVisibility: boolean;
}

/**
 *  表单逻辑
 * @param formRules 表单校验规则 reactive
 * @param buildRule 构建校验规则方法
 */
export function useFormLogic() {
  // 使用 Map 存储字段的可见性状态
  const {
    currentPageConfig,
    formModel,
    allFields,
    fieldIdIndex,
    fieldVisibilityMap,
    fieldOptionVisibilityMap,
    isPageForm,
    fieldOptionCheckStatusMap
  } = useUserFormInject();

  // 初始化所有字段的可见性状态
  const initializeFieldVisibility = () => {
    const newVisibilityMap = new Map<string, FieldVisibilityState>();
    allFields.value.forEach((field: BasicComponent) => {
      newVisibilityMap.set(field.vModel, {
        isVisible: true
      });
    });
    fieldVisibilityMap.value = newVisibilityMap;
  };

  /**
   * 计算字段是否应该显示
   * @param changedFieldId 变化的字段
   */
  const calculateVisibleFields = (changedFieldId: string, formRules: Ref<any>, buildRule: Function) => {
    // 清空上一次的变更记录
    const visibilityChanges: FieldVisibilityChange[] = [];
    const logicRuleMap = currentPageConfig.value?.logicRuleMap || {};

    // 本次选中的题目和选项
    const currentSelectedOptionIdMap = new Map<string, Set<string>>();
    // 记录选项发生变更的字段 用于清空选项的值
    const optionVisibilityChanges = new Set<string>();

    // 处理所有逻辑规则
    processLogicRules(changedFieldId, logicRuleMap, visibilityChanges, currentSelectedOptionIdMap, optionVisibilityChanges);

    // 处理选项选中状态
    processSelectedOptions(currentSelectedOptionIdMap);

    // 处理字段的默认值或者表单校验规则等
    handleFieldList(visibilityChanges, formRules, buildRule);
    // 处理选项变更导致选中的值无效
    handleOptionVisibilityChanges(optionVisibilityChanges);
  };

  /**
   * 处理选项变更导致选中的值无效
   */
  const handleOptionVisibilityChanges = (optionVisibilityChanges: Set<string>) => {
    optionVisibilityChanges.forEach(questionId => {
      if (Array.isArray(formModel.value[questionId])) {
        formModel.value[questionId] = [];
      } else {
        formModel.value[questionId] = null;
      }
    });
  };

  /**
   * 处理所有逻辑规则
   */
  const processLogicRules = (
    changedFieldId: string,
    logicRuleMap: Record<string, any>,
    visibilityChanges: FieldVisibilityChange[],
    currentSelectedOptionIdMap: Map<string, Set<string>>,
    optionVisibilityChanges: Set<string>
  ) => {
    Object.entries(logicRuleMap).forEach(([targetFormItemId, rule]) => {
      const { visibilityExpr, dependentFields, level, operation } = rule;
      if (!dependentFields || !dependentFields.includes(changedFieldId)) {
        return;
      }

      // 检查条件是否满足，包括子条件
      const isConditionMet = validateFormLogic(formModel.value, visibilityExpr);

      if (level === LogicLevel.FIELD) {
        processFieldLevelLogic(targetFormItemId, isConditionMet, visibilityChanges);
      } else if (level === LogicLevel.OPTION && operation) {
        processOptionLevelLogic(targetFormItemId, operation, isConditionMet, currentSelectedOptionIdMap, optionVisibilityChanges);
      }
    });
  };

  /**
   * 处理字段级别的逻辑
   */
  const processFieldLevelLogic = (
    targetFormItemId: string,
    isConditionMet: boolean,
    visibilityChanges: FieldVisibilityChange[]
  ) => {
    const currentState = fieldVisibilityMap.value.get(targetFormItemId);
    if (currentState) {
      const previousVisibility = currentState.isVisible;
      currentState.isVisible = isConditionMet;
      fieldVisibilityMap.value.set(targetFormItemId, currentState);

      // 记录变更
      if (previousVisibility !== isConditionMet) {
        visibilityChanges.push({
          fieldId: targetFormItemId,
          isVisible: isConditionMet,
          previousVisibility
        });
      }
      // 处理分页组件的特殊逻辑
      handlePaginationLogic(targetFormItemId, isConditionMet);
    }
  };

  /**
   * 处理分页组件的特殊逻辑
   */
  const handlePaginationLogic = (targetFormItemId: string, isConditionMet: boolean) => {
    if (targetFormItemId.startsWith("pagination")) {
      if (isPageForm.value && !isConditionMet) {
        currentPageConfig.value!.formBtns = true;
      } else if (isConditionMet) {
        currentPageConfig.value!.formBtns = false;
      }
    }
  };

  /**
   * 处理选项级别的逻辑
   */
  const processOptionLevelLogic = (
    targetFormItemId: string,
    operation: string,
    isConditionMet: boolean,
    currentSelectedOptionIdMap: Map<string, Set<string>>,
    optionVisibilityChanges: Set<string>
  ) => {
    if (operation === LogicOperation.SHOW) {
      handleOptionVisibility(targetFormItemId, isConditionMet, optionVisibilityChanges);
    } else if (operation === LogicOperation.CHECK) {
      handleOptionCheck(targetFormItemId, isConditionMet, currentSelectedOptionIdMap);
    }
  };

  /**
   * 处理选项可见性
   */
  const handleOptionVisibility = (targetFormItemId: string, isConditionMet: boolean, optionVisibilityChanges: Set<string>) => {
    const currentState = fieldOptionVisibilityMap.value.get(targetFormItemId);
    if (currentState) {
      const previousVisibility = currentState.isVisible;
      currentState.isVisible = isConditionMet;
      fieldOptionVisibilityMap.value.set(targetFormItemId, currentState);

      // 记录变更
      if (previousVisibility !== isConditionMet) {
        const [questionId] = targetFormItemId.split("_");
        optionVisibilityChanges.add(questionId);
      }
    }
  };

  /**
   * 处理选项选中状态
   */
  const handleOptionCheck = (
    targetFormItemId: string,
    isConditionMet: boolean,
    currentSelectedOptionIdMap: Map<string, Set<string>>
  ) => {
    const [questionId, optionId] = targetFormItemId.split("_");
    if (isConditionMet) {
      let checkOptionList = currentSelectedOptionIdMap.get(questionId);
      if (checkOptionList) {
        checkOptionList.add(optionId);
      } else {
        checkOptionList = new Set([optionId]);
      }
      currentSelectedOptionIdMap.set(questionId, checkOptionList);
    }
  };

  /**
   * 处理选中的选项
   */
  const processSelectedOptions = (currentSelectedOptionIdMap: Map<string, Set<string>>) => {
    if (currentSelectedOptionIdMap && currentSelectedOptionIdMap.size) {
      currentSelectedOptionIdMap.forEach((optionIds, questionId) => {
        if (optionIds.size) {
          fieldOptionCheckStatusMap.value.set(questionId, optionIds);
        }
      });
    }
  };

  /**
   * 处理字段的其他逻辑 比如校验规则 填写值等
   * @param visibilityChanges
   * @param formRules
   * @param buildRule
   */
  const handleFieldList = (visibilityChanges: FieldVisibilityChange[], formRules: Ref<any>, buildRule: Function) => {
    visibilityChanges.forEach((vc: FieldVisibilityChange) => {
      if (vc.isVisible !== vc.previousVisibility) {
        let triggerFormItem = allFields.value[fieldIdIndex.value[vc.fieldId]];
        if (vc.isVisible) {
          // 商品增加默认数量选中
          if (vc.fieldId && vc.fieldId!.startsWith("goods_select")) {
            formModel.value[vc.fieldId] = triggerFormItem?.config?.defaultValue;
          } else {
            // 设置默认值 如果有值的话使用值 没有的话默认值填充
            formModel.value[vc.fieldId] = getValueOrDefaultValue(
              toValue(formModel.value[vc.fieldId]),
              triggerFormItem?.config?.defaultValue
            );
          }
          buildRule(triggerFormItem, formRules, formModel);
        } else {
          removeRule(formRules, vc.fieldId);
          // 填充默认值
          formModel.value[vc.fieldId] = toValue(triggerFormItem?.config?.defaultValue);
          // 选项类型题目会有两个值 一个是记录选项 value 一个是 label
          if (isLabelTag(vc.fieldId)) {
            formModel.value[vc.fieldId + "label"] =
              undefined === triggerFormItem?.config?.defaultValue
                ? null
                : getCheckedLabel(triggerFormItem?.config?.defaultValue, triggerFormItem?.config?.options);
          }
          // 商品会有默认选中数量的默认值 会导致逻辑切换时默认值也提交了 如果有逻辑隐藏掉的商品不清空值就也会被计算进价格
          if (vc.fieldId && vc.fieldId!.startsWith("goods_select")) {
            formModel.value[vc.fieldId] = {};
          }
        }
      }
    });
  };

  /**
   * 判断值是否为空 不为空则返回 为空则返回默认值
   */
  const getValueOrDefaultValue = (value: any, defaultValue: any) => {
    if (value !== undefined && value !== null) {
      return value;
    }
    return defaultValue;
  };

  // 移除表单校验规则
  const removeRule = (formRules: Ref<any>, fieldId: string) => {
    delete formRules.value[fieldId];
  };

  // 判断字段是否可见
  const isFieldVisible = (fieldId: string) => {
    return fieldVisibilityMap.value.get(fieldId)?.isVisible ?? true;
  };

  return {
    initializeFieldVisibility,
    calculateVisibleFields,
    isFieldVisible
  };
}
